/**
 * 文件管理器组件
 * File Manager Component
 */

class FileManager {
  constructor() {
    this.currentPath = '/';
    this.currentView = 'grid'; // 'grid' or 'list'
    this.selectedFiles = new Set();
    this.files = [];
    this.folders = [];
    this.sortBy = 'name';
    this.sortOrder = 'asc';
    this.searchQuery = '';
    this.uploadQueue = [];
    this.isUploading = false;
    this.maxConcurrentUploads = 3;
    this.activeUploads = 0;
    
    // 文件类型和大小限制
    this.fileConstraints = {
      maxFileSize: 100 * 1024 * 1024, // 100MB
      allowedTypes: [
        'image/jpeg', 'image/png', 'image/webp', 'image/gif',
        'video/mp4', 'video/webm', 'video/avi', 'video/mov',
        'audio/mp3', 'audio/wav', 'audio/ogg', 'audio/m4a',
        'application/pdf', 'text/plain', 'text/csv',
        'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
        'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'application/zip', 'application/x-rar-compressed', 'application/x-7z-compressed'
      ]
    };
    
    this.init();
  }

  /**
   * 初始化文件管理器
   */
  init() {
    this.bindEvents();
    this.loadFiles();
    this.updateBreadcrumb();
  }

  /**
   * 验证文件
   */
  validateFile(file) {
    const errors = [];
    
    // 检查文件大小
    if (file.size > this.fileConstraints.maxFileSize) {
      const maxSizeMB = Math.round(this.fileConstraints.maxFileSize / (1024 * 1024));
      errors.push(`文件大小超出限制 (最大 ${maxSizeMB}MB)`);
    }
    
    // 检查文件类型
    if (!this.fileConstraints.allowedTypes.includes(file.type)) {
      errors.push(`不支持的文件类型: ${file.type || '未知类型'}`);
    }
    
    // 检查文件名
    if (!/^[^<>:"/\\|?*]+$/.test(file.name)) {
      errors.push('文件名包含非法字符');
    }
    
    return {
      valid: errors.length === 0,
      errors
    };
  }

  /**
   * 绑定事件
   */
  bindEvents() {
    // 返回按钮
    document.getElementById('back-btn').addEventListener('click', () => {
      window.location.href = '/';
    });

    // 视图切换
    document.getElementById('grid-view-btn').addEventListener('click', () => {
      this.switchView('grid');
    });

    document.getElementById('list-view-btn').addEventListener('click', () => {
      this.switchView('list');
    });

    // 新建文件夹
    document.getElementById('new-folder-btn').addEventListener('click', () => {
      this.showNewFolderModal();
    });

    // 上传文件
    document.getElementById('upload-btn').addEventListener('click', () => {
      this.toggleUploadArea();
    });

    this.bindUploadEvents();
    this.bindModalEvents();
    this.bindSearchEvents();
  }

  /**
   * 绑定上传相关事件
   */
  bindUploadEvents() {
    const uploadArea = document.getElementById('upload-area');
    const fileInput = document.getElementById('file-input');
    const selectFilesBtn = document.getElementById('select-files-btn');

    // 文件选择
    selectFilesBtn.addEventListener('click', () => {
      fileInput.click();
    });

    fileInput.addEventListener('change', (e) => {
      this.handleFileSelect(e.target.files);
    });

    // 拖拽上传
    uploadArea.addEventListener('dragover', (e) => {
      e.preventDefault();
      uploadArea.classList.add('upload-area-active');
    });

    uploadArea.addEventListener('dragleave', (e) => {
      e.preventDefault();
      uploadArea.classList.remove('upload-area-active');
    });

    uploadArea.addEventListener('drop', (e) => {
      e.preventDefault();
      uploadArea.classList.remove('upload-area-active');
      this.handleFileSelect(e.dataTransfer.files);
    });

    // 全局拖拽处理
    document.addEventListener('dragover', (e) => {
      e.preventDefault();
    });

    document.addEventListener('drop', (e) => {
      e.preventDefault();
      if (!uploadArea.contains(e.target)) {
        this.handleFileSelect(e.dataTransfer.files);
      }
    });
  }

  /**
   * 绑定模态框事件
   */
  bindModalEvents() {
    // 新建文件夹模态框
    const newFolderModal = document.getElementById('new-folder-modal');
    const closeFolderModal = document.getElementById('close-folder-modal');
    const cancelFolderBtn = document.getElementById('cancel-folder-btn');
    const createFolderBtn = document.getElementById('create-folder-btn');
    const folderNameInput = document.getElementById('folder-name-input');

    [closeFolderModal, cancelFolderBtn].forEach(btn => {
      btn.addEventListener('click', () => {
        this.hideNewFolderModal();
      });
    });

    createFolderBtn.addEventListener('click', () => {
      this.createFolder();
    });

    folderNameInput.addEventListener('keypress', (e) => {
      if (e.key === 'Enter') {
        this.createFolder();
      }
    });

    // 重命名模态框
    this.bindRenameModalEvents();
    
    // 上传进度模态框
    this.bindUploadProgressModalEvents();
  }  /*
*
   * 绑定搜索事件
   */
  bindSearchEvents() {
    const searchInput = document.getElementById('search-input');
    const sortSelect = document.getElementById('sort-select');

    searchInput.addEventListener('input', (e) => {
      this.searchQuery = e.target.value.toLowerCase();
      this.filterAndRenderFiles();
    });

    sortSelect.addEventListener('change', (e) => {
      this.sortBy = e.target.value;
      this.sortFiles();
      this.renderFiles();
    });
  }

  /**
   * 切换视图
   */
  switchView(view) {
    this.currentView = view;
    
    const gridViewBtn = document.getElementById('grid-view-btn');
    const listViewBtn = document.getElementById('list-view-btn');
    const gridView = document.getElementById('grid-view');
    const listView = document.getElementById('list-view');

    if (view === 'grid') {
      gridViewBtn.classList.add('bg-primary', 'text-white');
      listViewBtn.classList.remove('bg-primary', 'text-white');
      gridView.classList.remove('hidden');
      listView.classList.add('hidden');
    } else {
      listViewBtn.classList.add('bg-primary', 'text-white');
      gridViewBtn.classList.remove('bg-primary', 'text-white');
      listView.classList.remove('hidden');
      gridView.classList.add('hidden');
    }

    this.renderFiles();
  }

  /**
   * 显示新建文件夹模态框
   */
  showNewFolderModal() {
    const modal = document.getElementById('new-folder-modal');
    const input = document.getElementById('folder-name-input');
    
    modal.classList.remove('hidden');
    input.value = '';
    input.focus();
  }

  /**
   * 隐藏新建文件夹模态框
   */
  hideNewFolderModal() {
    const modal = document.getElementById('new-folder-modal');
    modal.classList.add('hidden');
  }

  /**
   * 切换上传区域显示
   */
  toggleUploadArea() {
    const uploadArea = document.getElementById('upload-area');
    uploadArea.classList.toggle('hidden');
  }  /**

   * 加载文件列表
   */
  async loadFiles() {
    try {
      this.showLoading();
      
      const response = await api.get(`/files?path=${encodeURIComponent(this.currentPath)}`);
      this.files = response.files || [];
      this.folders = response.folders || [];
      
      this.sortFiles();
      this.renderFiles();
      
    } catch (error) {
      console.error('加载文件失败:', error);
      notification.error('加载文件失败');
    } finally {
      this.hideLoading();
    }
  }

  /**
   * 渲染文件列表
   */
  renderFiles() {
    const allItems = [...this.folders, ...this.files];
    const filteredItems = this.filterItems(allItems);

    if (filteredItems.length === 0) {
      this.showEmptyState();
      return;
    }

    this.hideEmptyState();

    if (this.currentView === 'grid') {
      this.renderGridView(filteredItems);
    } else {
      this.renderListView(filteredItems);
    }
  }

  /**
   * 渲染网格视图
   */
  renderGridView(items) {
    const container = document.getElementById('file-grid');
    
    container.innerHTML = items.map(item => {
      const isFolder = item.type === 'folder';
      const icon = this.getFileIcon(item);
      const thumbnail = this.getFileThumbnail(item);
      
      return `
        <div class="file-item bg-white rounded-lg border border-neutral-200 p-3 text-center" 
             data-id="${item.id}" 
             data-name="${item.name}"
             data-type="${item.type}">
          <div class="relative mb-2">
            ${thumbnail ? 
              `<img src="${thumbnail}" alt="${item.name}" class="w-16 h-16 mx-auto object-cover rounded-md">` :
              `<div class="w-16 h-16 mx-auto flex items-center justify-center bg-neutral-100 rounded-md">
                <i class="fa ${icon} text-2xl text-neutral-500"></i>
              </div>`
            }
            <input type="checkbox" class="file-checkbox absolute top-1 right-1 rounded">
          </div>
          <div class="text-xs text-neutral-600 truncate" title="${item.name}">
            ${item.name}
          </div>
          ${!isFolder ? `<div class="text-xs text-neutral-400 mt-1">${this.formatFileSize(item.size)}</div>` : ''}
        </div>
      `;
    }).join('');

    this.bindFileEvents();
  }  /**

   * 获取文件缩略图
   */
  getFileThumbnail(item) {
    // 如果是图片文件，返回缩略图URL
    if (item.type === 'image' && item.thumbnail) {
      return item.thumbnail;
    }
    
    // 如果是视频文件，返回视频缩略图
    if (item.type === 'video' && item.thumbnail) {
      return item.thumbnail;
    }
    
    // 为演示目的，使用静态资源作为示例缩略图
    if (item.type === 'image') {
      const sampleImages = [
        '/static/image/wallhaven-571je1.webp',
        '/static/image/wallhaven-72pgxv.webp',
        '/static/image/wallhaven-g7gxqq.webp',
        '/static/image/wallhaven-gpp7re.webp',
        '/static/image/wallhaven-n65ew4.webp'
      ];
      return sampleImages[Math.floor(Math.random() * sampleImages.length)];
    }
    
    return null;
  }

  /**
   * 获取文件图标
   */
  getFileIcon(item) {
    if (item.type === 'folder') return 'fa-folder';
    
    const iconMap = {
      'image': 'fa-file-image-o',
      'video': 'fa-file-video-o',
      'audio': 'fa-file-audio-o',
      'pdf': 'fa-file-pdf-o',
      'word': 'fa-file-word-o',
      'excel': 'fa-file-excel-o',
      'powerpoint': 'fa-file-powerpoint-o',
      'text': 'fa-file-text-o',
      'code': 'fa-file-code-o',
      'archive': 'fa-file-archive-o'
    };
    
    return iconMap[item.type] || 'fa-file-o';
  }

  /**
   * 渲染列表视图
   */
  renderListView(items) {
    const container = document.getElementById('file-list');
    
    container.innerHTML = items.map(item => {
      const isFolder = item.type === 'folder';
      const icon = this.getFileIcon(item);
      
      return `
        <tr class="file-item border-b border-neutral-100 hover:bg-neutral-50" 
            data-id="${item.id}" 
            data-name="${item.name}"
            data-type="${item.type}">
          <td class="p-3">
            <input type="checkbox" class="file-checkbox rounded">
          </td>
          <td class="p-3">
            <div class="flex items-center gap-3">
              <i class="fa ${icon} text-neutral-500"></i>
              <span class="truncate">${item.name}</span>
            </div>
          </td>
          <td class="p-3 text-sm text-neutral-600">
            ${isFolder ? '-' : this.formatFileSize(item.size)}
          </td>
          <td class="p-3 text-sm text-neutral-600">
            ${this.getFileTypeText(item.type)}
          </td>
          <td class="p-3 text-sm text-neutral-600">
            ${this.formatDate(item.modified_at)}
          </td>
          <td class="p-3">
            <button class="file-action-btn btn-icon w-8 h-8" title="更多操作">
              <i class="fa fa-ellipsis-v text-neutral-500"></i>
            </button>
          </td>
        </tr>
      `;
    }).join('');

    this.bindFileEvents();
  }  /**
  
 * 工具函数
   */
  formatFileSize(bytes) {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  }

  formatDate(dateString) {
    const date = new Date(dateString);
    return date.toLocaleDateString('zh-CN') + ' ' + date.toLocaleTimeString('zh-CN', { 
      hour: '2-digit', 
      minute: '2-digit' 
    });
  }

  getFileTypeText(type) {
    const typeMap = {
      'folder': '文件夹',
      'image': '图片',
      'video': '视频',
      'audio': '音频',
      'pdf': 'PDF文档',
      'word': 'Word文档',
      'excel': 'Excel表格',
      'powerpoint': 'PPT演示',
      'text': '文本文件',
      'code': '代码文件',
      'archive': '压缩文件'
    };
    return typeMap[type] || '未知类型';
  }

  /**
   * 过滤文件
   */
  filterItems(items) {
    if (!this.searchQuery) return items;
    
    return items.filter(item => 
      item.name.toLowerCase().includes(this.searchQuery)
    );
  }

  /**
   * 排序文件
   */
  sortFiles() {
    const sortFn = (a, b) => {
      // 文件夹总是排在前面
      if (a.type === 'folder' && b.type !== 'folder') return -1;
      if (a.type !== 'folder' && b.type === 'folder') return 1;
      
      let comparison = 0;
      switch (this.sortBy) {
        case 'name':
          comparison = a.name.localeCompare(b.name);
          break;
        case 'date':
          comparison = new Date(a.modified_at) - new Date(b.modified_at);
          break;
        case 'size':
          comparison = (a.size || 0) - (b.size || 0);
          break;
        case 'type':
          comparison = a.type.localeCompare(b.type);
          break;
      }
      
      return this.sortOrder === 'asc' ? comparison : -comparison;
    };

    this.files.sort(sortFn);
    this.folders.sort(sortFn);
  }  /*
*
   * 显示/隐藏状态
   */
  showEmptyState() {
    document.getElementById('empty-state').classList.remove('hidden');
    document.getElementById('file-grid').classList.add('hidden');
    document.getElementById('file-list').classList.add('hidden');
  }

  hideEmptyState() {
    document.getElementById('empty-state').classList.add('hidden');
    document.getElementById('file-grid').classList.remove('hidden');
    document.getElementById('file-list').classList.remove('hidden');
  }

  showLoading() {
    document.getElementById('loading').classList.remove('hidden');
  }

  hideLoading() {
    document.getElementById('loading').classList.add('hidden');
  }

  /**
   * 更新面包屑导航
   */
  updateBreadcrumb() {
    const container = document.getElementById('breadcrumb-container');
    const pathParts = this.currentPath.split('/').filter(part => part);
    
    container.innerHTML = pathParts.map((part, index) => {
      const path = '/' + pathParts.slice(0, index + 1).join('/');
      return `
        <i class="fa fa-chevron-right text-neutral-400 text-xs"></i>
        <button class="breadcrumb-item text-primary hover:text-primary/80 transition-colors" data-path="${path}">
          ${part}
        </button>
      `;
    }).join('');

    // 绑定面包屑点击事件
    container.querySelectorAll('.breadcrumb-item').forEach(btn => {
      btn.addEventListener('click', (e) => {
        this.navigateToPath(e.target.dataset.path);
      });
    });

    // 首页面包屑
    document.getElementById('home-breadcrumb').addEventListener('click', () => {
      this.navigateToPath('/');
    });
  }

  /**
   * 导航到指定路径
   */
  async navigateToPath(path) {
    this.currentPath = path;
    this.updateBreadcrumb();
    await this.loadFiles();
  }

  /**
   * 绑定文件事件
   */
  bindFileEvents() {
    // 文件双击事件
    document.querySelectorAll('.file-item').forEach(item => {
      item.addEventListener('dblclick', (e) => {
        const type = item.dataset.type;
        const name = item.dataset.name;
        
        if (type === 'folder') {
          this.navigateToPath(this.currentPath + '/' + name);
        } else {
          this.previewFile(item.dataset.id);
        }
      });

      // 右键菜单
      item.addEventListener('contextmenu', (e) => {
        e.preventDefault();
        this.showContextMenu(e, item);
      });
    });

    // 文件选择
    document.querySelectorAll('.file-checkbox').forEach(checkbox => {
      checkbox.addEventListener('change', (e) => {
        this.handleFileSelection(e);
      });
    });
  }

  /**
   * 预览文件
   */
  previewFile(fileId) {
    const allFiles = [...this.files, ...this.folders].filter(item => item.type !== 'folder');
    const file = allFiles.find(f => f.id == fileId);
    
    if (!file) {
      notification.error('文件不存在');
      return;
    }
    
    // 初始化文件预览器
    if (!this.filePreview) {
      this.filePreview = new FilePreview({
        onDownload: (data) => {
          this.downloadFile(data.file.id);
        }
      });
    }
    
    // 预览文件
    this.filePreview.preview(file, allFiles);
  }

  /**
   * 下载文件
   */
  async downloadFile(fileId) {
    try {
      const file = [...this.files, ...this.folders].find(f => f.id == fileId);
      if (!file) {
        notification.error('文件不存在');
        return;
      }
      
      // 创建下载链接
      const link = document.createElement('a');
      link.href = `/api/files/download/${fileId}`;
      link.download = file.name;
      link.style.display = 'none';
      
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      
      notification.success('开始下载文件');
      
    } catch (error) {
      console.error('下载文件失败:', error);
      notification.error('下载文件失败');
    }
  }
}  /*
*
   * 处理文件选择
   */
  async handleFileSelect(files) {
    if (files.length === 0) return;

    const fileArray = Array.from(files);
    
    // 验证文件
    const validFiles = [];
    for (const file of fileArray) {
      const validation = this.validateFile(file);
      if (validation.valid) {
        validFiles.push(file);
      } else {
        notification.error(`${file.name}: ${validation.errors.join(', ')}`);
      }
    }

    if (validFiles.length === 0) {
      notification.warning('没有有效的文件可以上传');
      return;
    }

    // 添加到上传队列
    const newItems = validFiles.map(file => ({
      id: Date.now() + Math.random(),
      file,
      name: file.name,
      size: file.size,
      progress: 0,
      status: 'pending', // pending, uploading, completed, error, paused, cancelled
      error: null,
      xhr: null,
      startTime: null,
      speed: 0,
      remainingTime: 0
    }));

    this.uploadQueue.push(...newItems);
    this.showUploadProgressModal();
    
    // 如果没有正在上传，开始上传
    if (!this.isUploading) {
      await this.startUpload();
    }
  }

  /**
   * 开始上传
   */
  async startUpload() {
    if (this.isUploading) return;
    
    this.isUploading = true;
    this.processUploadQueue();
  }

  /**
   * 处理上传队列
   */
  async processUploadQueue() {
    while (this.hasUploadsPending() && this.activeUploads < this.maxConcurrentUploads) {
      const uploadItem = this.getNextPendingUpload();
      if (!uploadItem) break;
      
      this.startSingleUpload(uploadItem);
    }
    
    // 如果没有活跃的上传，标记上传完成
    if (this.activeUploads === 0) {
      this.isUploading = false;
      
      // 检查是否有失败的上传需要重试
      const failedUploads = this.uploadQueue.filter(item => item.status === 'error');
      if (failedUploads.length > 0) {
        notification.warning(`${failedUploads.length} 个文件上传失败，可以点击重试`);
      }
      
      // 上传完成后刷新文件列表
      const completedUploads = this.uploadQueue.filter(item => item.status === 'completed');
      if (completedUploads.length > 0) {
        setTimeout(() => {
          this.loadFiles();
        }, 1000);
      }
    }
  }

  /**
   * 检查是否有待上传的文件
   */
  hasUploadsPending() {
    return this.uploadQueue.some(item => item.status === 'pending');
  }

  /**
   * 获取下一个待上传的文件
   */
  getNextPendingUpload() {
    return this.uploadQueue.find(item => item.status === 'pending');
  }

  /**
   * 开始单个文件上传
   */
  async startSingleUpload(uploadItem) {
    this.activeUploads++;
    uploadItem.status = 'uploading';
    uploadItem.startTime = Date.now();
    this.updateUploadProgress();
    
    try {
      await this.uploadFile(uploadItem);
      uploadItem.status = 'completed';
      uploadItem.progress = 100;
      
    } catch (error) {
      uploadItem.status = 'error';
      uploadItem.error = error.message;
      console.error('上传失败:', error);
    } finally {
      this.activeUploads--;
      this.updateUploadProgress();
      
      // 继续处理队列
      setTimeout(() => {
        this.processUploadQueue();
      }, 100);
    }
  }

  /**
   * 上传单个文件
   */
  async uploadFile(uploadItem) {
    const formData = new FormData();
    formData.append('file', uploadItem.file);
    formData.append('path', this.currentPath);

    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      uploadItem.xhr = xhr; // 保存xhr引用用于取消上传
      
      let lastLoaded = 0;
      let lastTime = Date.now();
      
      xhr.upload.addEventListener('progress', (e) => {
        if (e.lengthComputable) {
          const currentTime = Date.now();
          const timeDiff = currentTime - lastTime;
          const loadedDiff = e.loaded - lastLoaded;
          
          // 计算上传速度
          if (timeDiff > 500) { // 每500ms更新一次速度
            uploadItem.speed = loadedDiff / (timeDiff / 1000); // bytes per second
            
            // 计算剩余时间
            const remainingBytes = e.total - e.loaded;
            uploadItem.remainingTime = uploadItem.speed > 0 ? remainingBytes / uploadItem.speed : 0;
            
            lastLoaded = e.loaded;
            lastTime = currentTime;
          }
          
          uploadItem.progress = (e.loaded / e.total) * 100;
          this.updateUploadProgress();
        }
      });
      
      xhr.addEventListener('load', () => {
        uploadItem.xhr = null;
        if (xhr.status === 200) {
          try {
            const response = JSON.parse(xhr.responseText);
            if (response.success) {
              resolve(response);
            } else {
              reject(new Error(response.message || '上传失败'));
            }
          } catch (error) {
            reject(new Error('解析响应失败'));
          }
        } else {
          reject(new Error(`上传失败: HTTP ${xhr.status}`));
        }
      });
      
      xhr.addEventListener('error', () => {
        uploadItem.xhr = null;
        reject(new Error('网络错误'));
      });
      
      xhr.addEventListener('abort', () => {
        uploadItem.xhr = null;
        reject(new Error('上传被取消'));
      });
      
      xhr.open('POST', '/api/files/upload');
      
      const token = localStorage.getItem('token');
      if (token) {
        xhr.setRequestHeader('Authorization', `Bearer ${token}`);
      }
      
      xhr.send(formData);
    });
  }

  /**
   * 更新上传进度
   */
  updateUploadProgress() {
    const container = document.getElementById('upload-progress-list');
    
    container.innerHTML = this.uploadQueue.map(item => {
      const statusIcon = {
        'pending': 'fa-clock-o text-neutral-400',
        'uploading': 'fa-spinner fa-spin text-primary',
        'completed': 'fa-check-circle text-success',
        'error': 'fa-exclamation-circle text-red-500',
        'paused': 'fa-pause text-warning',
        'cancelled': 'fa-times text-neutral-400'
      };
      
      const statusText = {
        'pending': '等待上传',
        'uploading': '上传中',
        'completed': '上传完成',
        'error': '上传失败',
        'paused': '已暂停',
        'cancelled': '已取消'
      };
      
      return `
        <div class="upload-item flex items-center gap-3 p-3 border-b border-neutral-100 last:border-b-0" data-id="${item.id}">
          <i class="fa ${statusIcon[item.status]}"></i>
          <div class="flex-1 min-w-0">
            <div class="text-sm font-medium text-neutral-700 truncate">${item.name}</div>
            <div class="flex items-center gap-2 text-xs text-neutral-500">
              <span>${this.formatFileSize(item.size)}</span>
              <span>•</span>
              <span>${statusText[item.status]}</span>
              ${item.status === 'uploading' && item.speed > 0 ? `
                <span>•</span>
                <span>${this.formatFileSize(item.speed)}/s</span>
                ${item.remainingTime > 0 ? `
                  <span>•</span>
                  <span>剩余 ${this.formatTime(item.remainingTime)}</span>
                ` : ''}
              ` : ''}
            </div>
            ${item.status === 'uploading' ? `
              <div class="w-full bg-neutral-200 rounded-full h-1.5 mt-2">
                <div class="bg-primary h-1.5 rounded-full transition-all" style="width: ${item.progress}%"></div>
              </div>
            ` : ''}
            ${item.status === 'error' && item.error ? `
              <div class="text-xs text-red-500 mt-1">${item.error}</div>
            ` : ''}
          </div>
          <div class="flex items-center gap-1">
            ${item.status === 'uploading' ? `
              <button class="pause-upload-btn btn-icon w-6 h-6 text-xs" data-id="${item.id}" title="暂停">
                <i class="fa fa-pause"></i>
              </button>
            ` : ''}
            ${item.status === 'paused' ? `
              <button class="resume-upload-btn btn-icon w-6 h-6 text-xs" data-id="${item.id}" title="继续">
                <i class="fa fa-play"></i>
              </button>
            ` : ''}
            ${item.status === 'error' ? `
              <button class="retry-upload-btn btn-icon w-6 h-6 text-xs" data-id="${item.id}" title="重试">
                <i class="fa fa-refresh"></i>
              </button>
            ` : ''}
            ${['pending', 'uploading', 'paused', 'error'].includes(item.status) ? `
              <button class="cancel-upload-btn btn-icon w-6 h-6 text-xs text-red-500" data-id="${item.id}" title="取消">
                <i class="fa fa-times"></i>
              </button>
            ` : ''}
            ${item.status === 'uploading' ? `
              <div class="text-xs text-neutral-500 ml-2 min-w-[3rem] text-right">
                ${Math.round(item.progress)}%
              </div>
            ` : ''}
          </div>
        </div>
      `;
    }).join('');
    
    // 绑定控制按钮事件
    this.bindUploadControlEvents();
    
    // 更新统计信息
    this.updateUploadStats();
  }
} 
 /**
   * 模态框相关方法
   */
  showUploadProgressModal() {
    document.getElementById('upload-progress-modal').classList.remove('hidden');
  }

  hideUploadProgressModal() {
    document.getElementById('upload-progress-modal').classList.add('hidden');
  }

  bindUploadProgressModalEvents() {
    const modal = document.getElementById('upload-progress-modal');
    const closeBtn = document.getElementById('close-upload-modal');
    const closeBtn2 = document.getElementById('close-upload-btn');
    const clearCompletedBtn = document.getElementById('clear-completed-btn');
    const pauseAllBtn = document.getElementById('pause-all-btn');
    const resumeAllBtn = document.getElementById('resume-all-btn');
    const retryFailedBtn = document.getElementById('retry-failed-btn');

    [closeBtn, closeBtn2].forEach(btn => {
      btn.addEventListener('click', () => {
        this.hideUploadProgressModal();
      });
    });

    clearCompletedBtn.addEventListener('click', () => {
      this.clearCompletedUploads();
    });

    pauseAllBtn.addEventListener('click', () => {
      this.pauseAllUploads();
    });

    resumeAllBtn.addEventListener('click', () => {
      this.resumeAllUploads();
    });

    retryFailedBtn.addEventListener('click', () => {
      this.retryFailedUploads();
    });
  }

  bindRenameModalEvents() {
    const modal = document.getElementById('rename-modal');
    const closeBtn = document.getElementById('close-rename-modal');
    const cancelBtn = document.getElementById('cancel-rename-btn');
    const confirmBtn = document.getElementById('confirm-rename-btn');

    [closeBtn, cancelBtn].forEach(btn => {
      btn.addEventListener('click', () => {
        this.hideRenameModal();
      });
    });

    confirmBtn.addEventListener('click', () => {
      this.confirmRename();
    });
  }

  /**
   * 创建文件夹
   */
  async createFolder() {
    const input = document.getElementById('folder-name-input');
    const name = input.value.trim();

    if (!name) {
      notification.warning('请输入文件夹名称');
      return;
    }

    if (!/^[^<>:"/\\|?*]+$/.test(name)) {
      notification.error('文件夹名称包含非法字符');
      return;
    }

    try {
      await api.post('/files/folder', {
        name,
        path: this.currentPath
      });

      notification.success('文件夹创建成功');
      this.hideNewFolderModal();
      this.loadFiles();

    } catch (error) {
      console.error('创建文件夹失败:', error);
      notification.error('创建文件夹失败');
    }
  }

  /**
   * 显示右键菜单
   */
  showContextMenu(event, fileItem) {
    const menu = document.getElementById('context-menu');
    const rect = menu.getBoundingClientRect();
    
    menu.style.left = `${event.clientX}px`;
    menu.style.top = `${event.clientY}px`;
    menu.classList.remove('hidden');

    // 点击其他地方关闭菜单
    const closeMenu = (e) => {
      if (!menu.contains(e.target)) {
        menu.classList.add('hidden');
        document.removeEventListener('click', closeMenu);
      }
    };

    setTimeout(() => {
      document.addEventListener('click', closeMenu);
    }, 0);

    // 绑定菜单项事件
    this.bindContextMenuEvents(fileItem);
  }

  bindContextMenuEvents(fileItem) {
    const menuItems = document.querySelectorAll('.context-menu-item');
    
    menuItems.forEach(item => {
      item.onclick = (e) => {
        e.stopPropagation();
        const action = item.textContent.trim();
        
        switch (action) {
          case '预览':
            this.previewFile(fileItem.dataset.id);
            break;
          case '下载':
            this.downloadFile(fileItem.dataset.id);
            break;
          case '重命名':
            this.showRenameModal(fileItem);
            break;
          case '删除':
            this.deleteFile(fileItem.dataset.id);
            break;
        }
        
        document.getElementById('context-menu').classList.add('hidden');
      };
    });
  }

  /**
   * 绑定上传控制事件
   */
  bindUploadControlEvents() {
    // 暂停上传
    document.querySelectorAll('.pause-upload-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.stopPropagation();
        this.pauseUpload(btn.dataset.id);
      });
    });

    // 继续上传
    document.querySelectorAll('.resume-upload-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.stopPropagation();
        this.resumeUpload(btn.dataset.id);
      });
    });

    // 重试上传
    document.querySelectorAll('.retry-upload-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.stopPropagation();
        this.retryUpload(btn.dataset.id);
      });
    });

    // 取消上传
    document.querySelectorAll('.cancel-upload-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.stopPropagation();
        this.cancelUpload(btn.dataset.id);
      });
    });
  }

  /**
   * 暂停上传
   */
  pauseUpload(itemId) {
    const item = this.uploadQueue.find(upload => upload.id == itemId);
    if (item && item.status === 'uploading' && item.xhr) {
      item.xhr.abort();
      item.status = 'paused';
      this.activeUploads--;
      this.updateUploadProgress();
      
      // 继续处理队列中的其他文件
      setTimeout(() => {
        this.processUploadQueue();
      }, 100);
    }
  }

  /**
   * 继续上传
   */
  resumeUpload(itemId) {
    const item = this.uploadQueue.find(upload => upload.id == itemId);
    if (item && item.status === 'paused') {
      item.status = 'pending';
      item.progress = 0;
      item.error = null;
      this.updateUploadProgress();
      
      // 如果没有正在上传，开始上传
      if (!this.isUploading) {
        this.startUpload();
      } else {
        this.processUploadQueue();
      }
    }
  }

  /**
   * 重试上传
   */
  retryUpload(itemId) {
    const item = this.uploadQueue.find(upload => upload.id == itemId);
    if (item && item.status === 'error') {
      item.status = 'pending';
      item.progress = 0;
      item.error = null;
      item.xhr = null;
      this.updateUploadProgress();
      
      // 如果没有正在上传，开始上传
      if (!this.isUploading) {
        this.startUpload();
      } else {
        this.processUploadQueue();
      }
    }
  }

  /**
   * 取消上传
   */
  cancelUpload(itemId) {
    const item = this.uploadQueue.find(upload => upload.id == itemId);
    if (item) {
      if (item.xhr) {
        item.xhr.abort();
        this.activeUploads--;
      }
      
      item.status = 'cancelled';
      item.xhr = null;
      this.updateUploadProgress();
      
      // 从队列中移除已取消的项目
      setTimeout(() => {
        this.uploadQueue = this.uploadQueue.filter(upload => upload.id !== itemId);
        this.updateUploadProgress();
        
        // 继续处理队列
        this.processUploadQueue();
      }, 1000);
    }
  }

  /**
   * 清除已完成的上传
   */
  clearCompletedUploads() {
    this.uploadQueue = this.uploadQueue.filter(item => 
      !['completed', 'cancelled'].includes(item.status)
    );
    this.updateUploadProgress();
  }

  /**
   * 格式化时间
   */
  formatTime(seconds) {
    if (seconds < 60) {
      return `${Math.round(seconds)}秒`;
    } else if (seconds < 3600) {
      return `${Math.round(seconds / 60)}分钟`;
    } else {
      return `${Math.round(seconds / 3600)}小时`;
    }
  }

  /**
   * 获取上传统计信息
   */
  getUploadStats() {
    const stats = {
      total: this.uploadQueue.length,
      pending: 0,
      uploading: 0,
      completed: 0,
      error: 0,
      paused: 0,
      cancelled: 0
    };

    this.uploadQueue.forEach(item => {
      stats[item.status]++;
    });

    return stats;
  }

  /**
   * 暂停所有上传
   */
  pauseAllUploads() {
    this.uploadQueue.forEach(item => {
      if (item.status === 'uploading' && item.xhr) {
        item.xhr.abort();
        item.status = 'paused';
      }
    });
    
    this.activeUploads = 0;
    this.updateUploadProgress();
  }

  /**
   * 继续所有上传
   */
  resumeAllUploads() {
    this.uploadQueue.forEach(item => {
      if (item.status === 'paused') {
        item.status = 'pending';
        item.progress = 0;
        item.error = null;
      }
    });
    
    this.updateUploadProgress();
    
    if (!this.isUploading) {
      this.startUpload();
    } else {
      this.processUploadQueue();
    }
  }

  /**
   * 重试失败的上传
   */
  retryFailedUploads() {
    this.uploadQueue.forEach(item => {
      if (item.status === 'error') {
        item.status = 'pending';
        item.progress = 0;
        item.error = null;
        item.xhr = null;
      }
    });
    
    this.updateUploadProgress();
    
    if (!this.isUploading) {
      this.startUpload();
    } else {
      this.processUploadQueue();
    }
  }

  /**
   * 更新上传统计显示
   */
  updateUploadStats() {
    const stats = this.getUploadStats();
    const statsContainer = document.getElementById('upload-stats');
    const emptyState = document.getElementById('upload-empty-state');
    const progressList = document.getElementById('upload-progress-list');
    
    if (stats.total === 0) {
      emptyState.classList.remove('hidden');
      progressList.classList.add('hidden');
      statsContainer.textContent = '';
      return;
    }
    
    emptyState.classList.add('hidden');
    progressList.classList.remove('hidden');
    
    const statusParts = [];
    if (stats.uploading > 0) statusParts.push(`${stats.uploading} 上传中`);
    if (stats.pending > 0) statusParts.push(`${stats.pending} 等待中`);
    if (stats.completed > 0) statusParts.push(`${stats.completed} 已完成`);
    if (stats.error > 0) statusParts.push(`${stats.error} 失败`);
    if (stats.paused > 0) statusParts.push(`${stats.paused} 已暂停`);
    
    statsContainer.textContent = `总计 ${stats.total} 个文件 (${statusParts.join(', ')})`;
  }
}

  /**
   * 刷新文件列表
   */
  async refresh() {
    await this.loadFiles();
    notification.success('文件列表已刷新 / Files list refreshed');
  }
}

// 导出FileManager类
window.FileManager = FileManager;

// 初始化文件管理器
document.addEventListener('DOMContentLoaded', () => {
  // 检查用户认证
  if (!auth.isAuthenticated()) {
    window.location.href = '/login.html';
    return;
  }
  
  window.fileManager = new FileManager();
});